/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.essilab.analyzer.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.channels.ReadableByteChannel;
import java.util.Map.Entry;
import java.util.*;

/**
 * This class is used to order words, present in a text, by decreasing number of
 * occurrence.
 *
 * @author Mohamed-Amine Chouchene, Ahcène Idinarere, Vincent Nock, Alain
 * Janin-Manificat
 */
public class Statistic {

    public static HashMap<String, Integer> stats = new HashMap<>();

//    public static void main(String[] args) throws FileNotFoundException {
//        evaluateQuantityText("/home/alain/Bureau/nimp.txt");
//    }

    /**
     * Take a path to a file in parameter and create a Map containing its words,
     * ordered by decreasing occurrence number.
     *
     * @param path String - path of the file to read.
     * @return Map<String,Integer> - Key : word Value : number of occurrence.
     * @throws FileNotFoundException
     */
    public static Map<String, Integer> evaluateQuantityText(String path) throws FileNotFoundException {

        //long start = System.currentTimeMillis();
        Scanner sc = new Scanner((ReadableByteChannel) (new FileInputStream(path).getChannel()));
        sc.useDelimiter("([^\\p{L}&&[^-]]+)"); // \\p{L} matches ascii letters
        String word = "";

        while (sc.hasNext()) {
            word = sc.next();
            Integer tmp = stats.put(word, 1);
            if (tmp != null) {
                stats.put(word, ++tmp);
            }
        }
        //System.out.println(sortByValue(stats));
        //System.out.println(System.currentTimeMillis()-start);
        return sortByValue(stats);

    }
    
    /**
     * Take a path to a file in parameter and create a Map containing its words,
     * ordered by decreasing occurrence number.
     *
     * @param text String - the text to read.
     * @return Map<String,Integer> - Key : word Value : number of occurrence.
     * @throws FileNotFoundException
     */
    public static Map<String, Integer> evaluateQuantityTextFromString(String text) {

        //long start = System.currentTimeMillis();
        Scanner sc = new Scanner(text);
        sc.useDelimiter("([^\\p{L}&&[^-]]+)"); // \\p{L} matches ascii letters
        String word = "";

        while (sc.hasNext()) {
            word = sc.next();
            Integer tmp = stats.put(word, 1);
            if (tmp != null) {
                stats.put(word, ++tmp);
            }
        }
        System.out.println(sortByValue(stats));
        //System.out.println(System.currentTimeMillis()-start);
        return sortByValue(stats);

    }

    /**
     * Sort a map by value.
     *
     * @param <K> any Class.
     * @param <V> a Class that implements Comparable<V> interface.
     * @param map Map - the map to sort by value.
     * @return Map<K, V> - a map ordered with given map hash ordered by value.
     */
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {

        List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
        Collections.sort(list, new Comparator<Entry<K, V>>() {

            @Override
            public int compare(Entry<K, V> o1, Entry<K, V> o2) {
                return (o2.getValue()).compareTo(o1.getValue());
            }
        });

        Map<K, V> result = new LinkedHashMap<>();
        for (Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }
}
